package controllers

import (
	"fmt"
	"github.com/jinzhu/gorm"
	"gopkg.in/kataras/iris.v6"
	"layim/models"
	"os"
	"strconv"
	"encoding/base64"
	"strings"
	"gopkg.in/kataras/iris.v6/adaptors/websocket"
	"github.com/kataras/go-serializer"
	"layim/storage"
	"io"
	"layim/helper"
	"github.com/kataras/go-serializer/json"
)

//ChatController IM总控
type ChatController struct {
	Orm   *gorm.DB
	WsCon websocket.Connection
}

//查看聊天室成员
func (h *ChatController) Group(this *iris.Context) {
	roomId, err := this.URLParamInt64("id")
	userId, _ := this.URLParamInt64("userid")
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Code: 1, Message: err.Error()})
		return
	}

	members := []models.RoomUser{}
	if findErr := h.Orm.Find(&members, &models.RoomUser{RoomId: roomId}).Error; findErr != nil {
		this.JSON(iris.StatusOK, responseJSON{Code: 1, Message: findErr.Error()})
		return
	}

	list := []UserInfo{}
	for _, user := range members {
		if user.Id == userId { //用户列表中不显示自己
			continue
		}
		tmpUser := &models.User{}
		if h.Orm.First(tmpUser, &models.User{Id: user.UserId}).Error != nil {
			continue
		}
		list = append(list, UserInfo{
			Id:     tmpUser.Id,
			Name:   tmpUser.Username,
			Avatar: tmpUser.Avatar,
			Sign:   tmpUser.Sign,
		})
	}
	this.JSON(iris.StatusOK, responseJSON{
		Code:    0,
		Message: "",
		Data:    map[string]interface{}{"list": list},
	})
}

//通过用户ID获取用户所有的分组记录
func (h *ChatController) getUserGroupsById(userid int64) []models.Group {
	_groups := []models.Group{}
	h.Orm.Find(&_groups, &models.Group{UserId: userid}) //查询所有该用户下的分组
	groups := []models.Group{}                          //添加默认分组<<我的朋友>>
	groups = append(groups, models.Group{Id: 0, Name: "我的朋友", UserId: userid})
	groups = append(groups, _groups...)
	return groups
}

//获取聊天群组分类
func (h *ChatController) getUserRoomsById(userid int64) []models.Room {
	roomUser := []models.RoomUser{}
	if h.Orm.Find(&roomUser, &models.RoomUser{UserId: int64(userid)}).RecordNotFound() {
		return []models.Room{}
	}
	rooms := []models.Room{}
	for _, v := range roomUser {
		room := models.Room{}
		if !h.Orm.First(&room, &models.Room{Id: v.RoomId}).RecordNotFound() {
			rooms = append(rooms, room)
		}
	}
	return rooms
}

//获取用户信息
func (h ChatController) getUserInfoById(userid int64) (models.User, error) {
	mine := models.User{}
	err := h.Orm.First(&mine, &models.User{Id: int64(userid)}).Error
	return mine, err
}

//Friends 前端请求朋友路由分组
func (h *ChatController) Friends(this *iris.Context) {
	userid, err := strconv.Atoi(this.FormValue("userid"))
	if err != nil {
		this.JSON(iris.StatusOK, &responseJSON{Errcode: 1, Message: err.Error()})
		return
	}
	mine := models.User{}
	if mine, err = h.getUserInfoById(int64(userid)); err != nil {
		this.JSON(iris.StatusOK, &responseJSON{Errcode: 1, Message: "系统异常,无法服务"})
		return
	}
	friendList, roomList := []GroupList{}, []GroupInfo{} //好友分组列表 ,聊天群列表
	room := h.getUserRoomsById(int64(userid))
	for _, v := range room {
		roomList = append(roomList, GroupInfo{Id: v.Id, Name: v.Name, Avatar: v.Avatar})
	}
	groups := h.getUserGroupsById(int64(userid))
	for _, group := range groups { //获取分组下的列表
		list_son := GroupList{Name: group.Name, Id: group.Id}
		group_users := []models.Friend{}
		if h.Orm.Where("group_id = ? and user_id = ? ", group.Id, group.UserId).Find(&group_users).Error == nil {
			userList := []UserInfo{}
			for _, user := range group_users {
				if tmpUser, err := h.getUserInfoById(user.FriendId); err != nil {
					continue
				} else {
					userList = append(userList, UserInfo{
						Sign:   tmpUser.Sign,
						Name:   tmpUser.Username,
						Id:     tmpUser.Id,
						Avatar: tmpUser.Avatar})
				}
			}
			list_son.List = userList
		}
		friendList = append(friendList, list_son)
	}
	onlineStatus := ""
	if mine.Status == 1 {
		onlineStatus = "online"
	} else {
		onlineStatus = "offline"
	}
	this.JSON(iris.StatusOK, &FriendAPIJSON{Code: 0, Msg: "获取成功", Data: map[string]interface{}{
		"mine": UserInfo{
			Name:   mine.Username,
			Sign:   mine.Sign,
			Avatar: mine.Avatar,
			Id:     mine.Id,
			Status: onlineStatus,
		},
		"friend": friendList,
		"group":  roomList,
	}})
}

//提交添加好友
func (h *ChatController) AddFriend(this *iris.Context) {
	loginUser, _ := helper.GetLoginId(this)
	if loginUser == 0 {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "登录过期，请刷新"})
		return
	}
	friendId, ferr := strconv.Atoi(this.FormValue("friendid"))
	grouid, err := strconv.Atoi(this.FormValue("groupid"))
	groupCondition := &models.Group{UserId: loginUser, Id: int64(grouid)}
	friendInfo := &models.User{}
	result := ferr != nil || err != nil ||
		(grouid != 0 && h.Orm.First(&models.Group{}, groupCondition).Error != nil) ||
		h.Orm.First(friendInfo, &models.User{Id: int64(friendId)}).Error != nil
	if result {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "数据异常"})
		return
	}
	if loginUser == int64(friendId) {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "不要加自己为好友"})
		return
	}
	friend := &models.Friend{FriendId: int64(friendId), UserId: loginUser}
	if h.Orm.First(&models.Friend{}, friend).Error == nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "已为好友"})
		return
	}
	h.Orm.Begin()
	friend = &models.Friend{UserId: loginUser, FriendId: int64(friendId), GroupId: int64(grouid)}
	if err = h.Orm.Create(friend).Error; err != nil {
		h.Orm.Rollback()
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: err.Error()})
		return
	}

	if err = h.Orm.Create(&models.Friend{UserId: int64(friendId), FriendId: loginUser, GroupId: int64(grouid)}).Error; err != nil {
		h.Orm.Rollback()
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: err.Error()})
		return
	}

	h.Orm.Commit()
	this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "添加好友成功", Data: map[string]interface{}{
		"type":     "friend",
		"avatar":   friendInfo.Avatar,
		"username": friendInfo.Username,
		"groupid":  grouid,
		"id":       friendInfo.Id,
		"sign":     friendInfo.Sign,
	}})
	return
}

//加入聊天群
func (h *ChatController) AddRoom(this *iris.Context) {
	roomid, err := strconv.Atoi(this.FormValue("roomid"))
	loginId, _ := helper.GetLoginId(this)
	if loginId == 0 {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "登录过期，无法操作"})
		return
	}
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "群号错误"})
		return
	}
	room := &models.Room{}
	if h.Orm.First(room, &models.Room{Id: int64(roomid)}).RecordNotFound() {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "群组不存在"})
		return
	}
	if room.UserId == loginId { //自己的群组
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "不可加入自己的群组"})
		return
	}
	if !h.Orm.First(&models.RoomUser{}, &models.RoomUser{UserId: loginId, RoomId: room.Id}).RecordNotFound() {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "已经在群组中"})
		return
	}

	if err := h.Orm.Create(&models.RoomUser{UserId: loginId, RoomId: room.Id}).Error; err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "加入群组失败"})
		return
	} else {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "加入群组成功"})
		return
	}
}

//查找好友
func (h *ChatController) Find(this *iris.Context) {
	loginid, _ := helper.GetLoginId(this)
	if loginid == 0 {
		this.Write([]byte("登录过期，请刷新页面"))
		return
	}
	//查找我的分组
	groups := h.getUserGroupsById(int64(loginid))
	this.Render("find.html", map[string]interface{}{"groups": groups})
}

//删除群组 联系人 分组
func (h *ChatController) Delete(this *iris.Context) {
	_type := this.FormValue("type")
	loginId, _ := helper.GetLoginId(this)
	if loginId == 0 {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "登录过期，无法操作"})
		return
	}
	switch _type {
	case "friend": //删除好友
		_id, err := strconv.Atoi(this.FormValue("id"))
		if err != nil {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "传入key错误"})
			return
		}
		id := int64(_id)
		h.Orm.Delete(models.Friend{}, &models.Friend{UserId: int64(loginId), FriendId: id})  //删除此用户的好友信息
		h.Orm.Delete(models.Friend{}, &models.Chatlog{UserId: int64(loginId), FriendId: id}) //删除两人的聊天列表
		this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "删除好友成功"})
	case "group":
		groupname := this.FormValue("name")
		group := models.Group{}
		if h.Orm.Find(&group, &models.Group{Name: groupname, UserId: int64(loginId)}).Error != nil {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "群组信息不存在"})
			return
		}
		groupId := group.Id
		query := "group_id = ? and user_id = ?"
		//todo 删除数据存在BUG,无法更新表内的数据.
		h.Orm.Model(models.Friend{}).Where(query, groupId, loginId).Set("group_id", 0)
		if h.Orm.Delete(&models.Group{Id: groupId}).RowsAffected == 0 {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "删除群组失败"})
			return
		}
		this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "删除群组成功"})
		return
	case "room":

	}
}

//ajax查寻
func (h *ChatController) AjaxFind(this *iris.Context) {
	findType := this.FormValue("type")
	findId := this.FormValue("number")
	if findType == "" || findId == "" {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "没有此用户"})
		return
	}
	if !helper.VerifyInt(findId) {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "查找号码不正确"})
		return
	}
	numid, _ := strconv.Atoi(findId)
	if findType == "friend" {
		friend := &models.User{}
		if h.Orm.First(friend, &models.User{Id: int64(numid)}).Error != nil {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "没有此用户"})
			return
		} else {
			var status string
			if friend.Status == 1 {
				status = "online"
			} else {
				status = "offline"
			}
			this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "friend", Data: UserInfo{
				Id:     friend.Id,
				Name:   friend.Username,
				Status: status,
				Avatar: friend.Avatar,
			}})
			return
		}
	}
	if findType == "group" {
		room := models.Room{}
		if h.Orm.First(&room, &models.Room{Id: int64(numid)}).Error != nil {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "查找的群号不存在"})
			return
		} else {

			this.JSON(iris.StatusOK, responseJSON{
				Errcode: 0,
				Message: "group",
				Data: GroupInfo{
					Id:     room.Id,
					Name:   room.Name,
					Avatar: room.Avatar,
				}})
			return
		}
	}
	this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "数据错误"})
}

//改变在线状态
func (h *ChatController) Change(this *iris.Context) {
	userid, err := strconv.Atoi(this.FormValue("userid"))
	if err == nil {
		_status := this.FormValue("status")
		var status int64
		if _status == "online" {
			status = 1
		} else {
			status = 0
		}
		user := &models.User{}
		if h.Orm.First(user, &models.User{Id: int64(userid)}).Error == nil {
			user.Status = status
			if h.Orm.Save(user).RowsAffected != 0 {
				this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: _status})
				return
			}
		}
	}
	this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "无法修改在线状态"})
}

//查看聊天记录
func (h *ChatController) ChatLog(this *iris.Context) {
	userid, _ := helper.GetLoginId(this)
	_type := this.URLParam("type")
	toid, _ := this.URLParamInt64("id")
	params := map[string]interface{}{}
	if _type == "friend" {
		fmt.Println("userid", userid, "toid", toid)
		if userid <= 0 || toid == 0 {
			this.Write([]byte("错误1"))
			return
		}
		user := &models.User{}
		if h.Orm.First(user, &models.User{Id: userid}).Error != nil {
			this.Write([]byte("错误2"))
			return
		}
		friend := &models.User{}
		if h.Orm.First(friend, models.User{Id: toid}).Error != nil {
			this.Write([]byte("错误3"))
			return
		}
		chat_log := []models.Chatlog{}
		query := "(user_id = ? and friend_id =?) or (user_id = ? and friend_id =?)"
		h.Orm.Where(query, userid, toid, toid, userid).Find(&chat_log)
		data := []ChatList{}
		for _, v := range chat_log {
			if v.UserId == userid {
				data = append(data, ChatList{
					Id:      v.UserId,
					Time:    helper.FormatTime(v.Time),
					Name:    user.Username,
					Avatar:  user.Avatar,
					Content: v.Message})
			} else {
				data = append(data, ChatList{
					Id:      v.UserId,
					Time:    helper.FormatTime(v.Time),
					Name:    friend.Username,
					Avatar:  friend.Avatar,
					Content: v.Message})
			}
		}
		params["chatlog"], _ = serializer.SerializeToString(json.ContentType, data, nil)

		params["listtpl"] = `{{# layui.each(d.data, function(index, item){
                if(item.id == parent.layui.layim.cache().mine.id){ }}
                <li class="layim-chat-mine">
                    <div class="layim-chat-user">
                    <img src="{{ item.avatar }}">
                    <cite><i>{{ item.time }}</i>{{ item.username }}</cite>
                </div>
                <div class="layim-chat-text">{{ layui.layim.content(item.content) }}</div>
                </li>
                {{# } else { }}
                <li>
                <div class="layim-chat-user">
                    <img src="{{ item.avatar }}">
                    <cite>{{ item.username }}<i>{{ item.time }}</i></cite>
                </div>
                <div class="layim-chat-text">{{ layui.layim.content(item.content) }}</div>
                </li>
                {{# }
                }); }}`
	} else {
		//todo 读取聊天室消息记录
	}
	if err := this.Render("chatlog.html", params); err != nil {
		fmt.Println(err.Error())
	}

}

//前端登陆
func (h *ChatController) Login(this *iris.Context) {
	username := this.FormValue("username")
	if username == "" {
		this.JSON(iris.StatusOK, responseJSON{
			Errcode: 1,
			Message: "账号不能为空",
		})
		return
	}
	loguser := &models.User{}
	password := this.FormValue("password")
	if h.Orm.First(loguser, &models.User{Username: username}).Error != nil {
		this.JSON(iris.StatusOK, responseJSON{
			Errcode: 1,
			Message: "账号不存在,请重试",
		})
		return
	}

	if loguser.Password != password {
		this.JSON(iris.StatusOK, responseJSON{
			Errcode: 1,
			Message: "登陆失败,请重试",
		})
		return
	}

	if loguser.Token != "" {
		url := "http://" + this.Host() + "/verify-email?token=" + loguser.Token
		this.JSON(iris.StatusOK, responseJSON{
			Errcode: 1,
			Message: "账号未验证,请先验证账号",
			Data:    "/sendmail?type=register&email=" + loguser.Email + "&url=" + base64.URLEncoding.EncodeToString([]byte(url)),
		})
		return
	}

	//设置登陆session
	this.Session().Set("login_userid", loguser.Id)
	this.JSON(iris.StatusOK, responseJSON{
		Errcode: 0,
		Message: "登陆成功",
		Data: map[string]interface{}{
			"userid": loguser.Id},
	})
}

//上传图片接口地址
func (h *ChatController) Upload(this *iris.Context) {
	//上传图片ƒ
	field := this.URLParam("field")
	file, fh, err := this.FormFile(field)
	if file != nil {
		file.Close()
	}
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "打开上传临时文件失败:" + err.Error()})
		return
	}
	fileInfo := strings.Split(fh.Filename, ".")
	savePath := "upload/" + helper.NowDate("Y-m-d") + "-" + helper.GetRandomStr(10, helper.RANDOM_ONLYINT) + "." + fileInfo[len(fileInfo)-1]

	out, err := os.OpenFile(savePath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "上传失败:" + err.Error()})
		return
	}
	defer out.Close()
	io.Copy(out, file)
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "上传失败:" + err.Error()})
		return
	}
	path, err := (&storage.Nos{}).UploadFile(savePath) //上传到nos上
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "上传文件成功", Data: savePath})
		return
	}
	if strings.Index(savePath, "upload/") == 0 {
		os.Remove(savePath)
	} //删除本地文件
	this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "上传文件成功", Data: path})

}

//前端注册
func (h *ChatController) Register(this *iris.Context) {
	if !this.IsAjax() {
		this.Render("register.html", nil)
		return
	}
	email := this.FormValue("email")
	if !helper.VerifyEmail(email) {
		this.JSON(iris.StatusOK, responseJSON{
			Errcode: 1,
			Message: "邮箱格式不正确",
		})
		return
	}
	reguser := &models.User{}
	password := this.FormValue("password")
	if h.Orm.First(reguser, &models.User{Email: email}).Error == nil {
		this.JSON(iris.StatusOK, responseJSON{
			Errcode: 1,
			Message: "无法注册用户,请换个邮箱再试",
		})
	} else {
		nickname := this.FormValue("username")
		reguser.Email = email
		reguser.Password = password
		if nickname == "" {
			reguser.Username = "用户:" + helper.GetRandomStr(3, helper.RANDOM_ONLYINT) //随机一个用户名
		} else {
			reguser.Username = nickname
		}
		reguser.Avatar = this.FormValue("avatar")
		reguser.Token = helper.GetRandomStr(13, helper.RANDOM_ONLYSTR)
		if h.Orm.Save(reguser).Error == nil {
			url := "http://" + this.Host() + "/verify-email?token=" + reguser.Token
			helper.SendEmail("注册账号激活", url, []string{email}, this)
			this.JSON(iris.StatusOK, responseJSON{
				Errcode: 0,
				Message: "保存用户成功,请点击邮件的连接激活本账号",
				Data:    "/sendmail?type=register&email=" + email + "&url=" + base64.URLEncoding.EncodeToString([]byte(url)),
			})
		} else {
			this.JSON(iris.StatusOK, responseJSON{
				Errcode: 1,
				Message: "保存用户失败",
			})
		}
	}
}

func (h *ChatController) EditInfo(this *iris.Context) {
	loginUserId, err := helper.GetLoginId(this)
	if err != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "登陆超时"})
		return
	}
	loginUser := &models.User{}
	if h.Orm.First(loginUser, &models.User{Id: loginUserId}).Error != nil {
		this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "系统异常"})
		return
	}

	if !this.IsAjax() {
		this.Render("editinfo.html", map[string]interface{}{
			"sign":     loginUser.Sign,
			"username": loginUser.Username,
			"avatar":   loginUser.Avatar,
			"id":       loginUser.Id,
		})
	} else {
		loginUser.Avatar = this.FormValue("avatar")
		loginUser.Sign = this.FormValue("sign")
		loginUser.Username = this.FormValue("username")
		if h.Orm.Save(loginUser).RowsAffected > 0 {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "修改成功"})
		} else {
			this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: "修改失败"})
		}
	}
}

//更改签名
func (h *ChatController) Sign(this *iris.Context) {
	userid, err := strconv.Atoi(this.FormValue("userid"))
	sign := this.FormValue("sign")
	if err == nil {
		user := &models.User{}
		if h.Orm.First(user, &models.User{Id: int64(userid)}).Error == nil {
			user.Sign = sign
			if h.Orm.Save(user).RowsAffected == 0 {
				this.JSON(iris.StatusOK, responseJSON{Errcode: 1, Message: err.Error()})
				return
			}
		}
	}
	this.JSON(iris.StatusOK, responseJSON{Errcode: 0, Message: "修改成功"})
}

//MsgBox轮询地址
func (h *ChatController) Msgbox(this *iris.Context) {
	this.Render("msgbox.html", map[string]interface{}{
		"listtpl": `
		{{# layui.each(d.data, function(index, item){
		  if(item.from){ }}
		    <li data-uid="{{ item.from }}" data-fromGroup="{{ item.from_group }}">
		      <a href="/u/{{ item.from }}/" target="_blank">
			<img src="{{ item.user.avatar }}" class="layui-circle layim-msgbox-avatar">
		      </a>
		      <p class="layim-msgbox-user">
			<a href="/u/{{ item.from }}/" target="_blank">{{ item.user.username||'' }}</a>
			<span>{{ item.time }}</span>
		      </p>
		      <p class="layim-msgbox-content">
			{{ item.content }}
			<span>{{ item.remark ? '附言: '+item.remark : '' }}</span>
		      </p>
		      <p class="layim-msgbox-btn">
			<button class="layui-btn layui-btn-small" data-type="agree">同意</button>
			<button class="layui-btn layui-btn-small layui-btn-primary" data-type="refuse">拒绝</button>
		      </p>
		    </li>
		  {{# } else { }}
		    <li class="layim-msgbox-system">
		      <p><em>系统：</em>{{ item.content }}<span>{{ item.time }}</span></p>
		    </li>
		  {{# }
		}); }}
		`,
	})
}

func (h *ChatController) Logout(this *iris.Context) {
	this.SessionDestroy()
	this.JSON(iris.StatusOK, responseJSON{Errcode: 0})
}
